Skip to content

Conversation

@Half-Shot
Copy link
Contributor

Checklist

  • Tests written for new code (and old code if feasible).
  • New or updated public/exported symbols have accurate TSDoc documentation.
  • Linter and other CI checks pass.
  • Sign-off given on the changes (see CONTRIBUTING.md).

Comment on lines +279 to 290
case MembershipKind.RTC:
return data.rtc_transports[0];
case "session":
switch (data.focus_active.focus_selection) {
case "multi_sfu":
return data.foci_preferred[0];
case "oldest_membership":
if (CallMembership.equal(this, oldestMembership)) return data.foci_preferred[0];
if (oldestMembership !== undefined) return oldestMembership.getTransport(oldestMembership);
break;
case MembershipKind.Session:
if (data.focus_active.focus_selection === "oldest_membership") {
// For legacy events we only support "oldest_membership"
if (CallMembership.equal(this, oldestMembership)) return data.foci_preferred[0];
if (oldestMembership !== undefined) return oldestMembership.getTransport(oldestMembership);
}
break;
}
return undefined;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general the changes to the call membership are much more straight forward than what I anticipated. this seems to be the main functional change.

Is there anything else in the code that gets more complicated because of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, I only removed things which didn't break other files or ECall / EWeb. I think the conflicts with the other PRs may be high.

Comment on lines 373 to 383
const content = e.getContent<RtcMembershipData>();
// Ensure the slot ID of the membership matches the state
if (content.slot_id !== slotId) {
console.log("Invalid slot ID", content.slot_id, slotId);
return false;
}
if (content.application.type !== slotDescription.application) {
console.log("Invalid application.type", content.application.type, slotDescription.application);
return false;
}
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this all covered by:

if (!deepCompare(membership.slotDescription, slotDescription))

which is done later?

Copy link
Member

@BillCarsonFr BillCarsonFr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sane, I have some minor comments. It is a bit big of a change to see the precise change of logic but ok for me

let client: MockClient;
let room: Room;
const focusActive: LivekitFocusSelection = {
const focusActive = Object.freeze({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL. Looks like this needs some strict mode? How is it defined? or maybe it is default?

describe("LegacyMembershipManager", () => {
beforeEach(() => {
// Provide a default mock that is like the default "non error" server behaviour.
(client._unstable_sendDelayedStateEvent as Mock<any>).mockResolvedValue({ delay_id: "id" });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference with this notation jest.mocked(client._unstable_sendDelayedStateEvent).mockResolvedValue({ delay_id: "id" }); ?
That I think I usually see for that

@@ -0,0 +1,11 @@
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyrights

CallNotify = "org.matrix.msc4075.call.notify",
RTCNotification = "org.matrix.msc4075.rtc.notification",
RTCDecline = "org.matrix.msc4310.rtc.decline",
RTCSlot = "org.matrix.msc4143.rtc.slot",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes I see that we use new UnstableValue(stable, mcxxx.unstable) and other times not. Any reason not to use it everytime? Combined with EitherAnd and the findIn it looks pretty useful, WDYT?

@@ -0,0 +1,121 @@
import { type IContent } from "../../matrix.ts";
Copy link
Member

@BillCarsonFr BillCarsonFr Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing ™️

});
}
public static getRtcSlot(
room: Pick<Room, "getLiveTimeline" | "roomId">,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that's new, we need the timelime now. I guess it is the only to access state?

}
public static getRtcSlot(
room: Pick<Room, "getLiveTimeline" | "roomId">,
slotDescription: SlotDescription,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently read the code_style.md and I think it is recommanding to use Optional<X> instead of RtcSlotEventContent | null but it is used almost no where :D

}
if (
"type" in slotContent.application === false ||
slotContent.application.type !== slotDescription.application
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure to read correctly but if application.type and slotDescription.application should be the same, maybe we have a naming problem? Can we use slotDescription.applicationType?

/**
* Handles sending membership for MSC3401 RTC events.
*/
export class LegacyMembershipManager extends MembershipManager<SessionMembershipData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently read the style guide so 😇

  1. There should be approximately one interface, class, or enum per file unless the file is named
    "types.ts", "global.d.ts", or ends with "-types.ts".

* This exclusively sends RTCMembershipData
*/
export class StickyEventMembershipManager extends MembershipManager {
export class StickyEventMembershipManager extends MembershipManager<RtcMembershipData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I invoke the style guide rule number 30 ⚡️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants